package com.maycurobj.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.maycur.developer.sdk.common.exception.MaycurException;
import com.maycur.developer.sdk.maycur.ultimate.openapi.request.*;
import com.maycur.developer.sdk.maycur.ultimate.openapi.request.budget.PostBudgetRequest;
import com.maycur.developer.sdk.maycur.ultimate.openapi.request.form.GetFormReimburseRequest;
import com.maycur.developer.sdk.maycur.ultimate.openapi.request.masterdata.PostReferenceDataDetailQueryRequest;
import com.maycur.developer.sdk.maycur.ultimate.openapi.response.*;
import com.maycur.developer.sdk.maycur.ultimate.openapi.response.budget.PostBudgetResponse;
import com.maycur.developer.sdk.maycur.ultimate.openapi.response.form.GetFormReimburseResponse;
import com.maycur.developer.sdk.maycur.ultimate.openapi.response.masterdata.PostReferenceDataDetailQueryResponse;
import com.maycurobj.entity.bim.IamLeaveUser;
import com.maycurobj.entity.oa.ContractManagementEntity;
import com.maycurobj.pojo.*;
import com.maycurobj.repository.bim.IamLeaveUserRepository;
import com.maycurobj.repository.oa.ContractManagementRepository;
import com.maycurobj.util.DingMessageUtil;
import com.maycurobj.view.FeiYongLXEnum;
import com.maycurobj.view.LegalEntityBizEnum;
import com.maycurobj.service.http.MaycurApiService;
import com.maycurobj.util.NormalUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 每刻接口服务
 */
@Service
@Slf4j
public class MaycurService {

    @Autowired
    private MaycurApiService maycurApiService;

    @Autowired
    private DingMessageUtil dingMessageUtil;

    @Value("${maycurprop.openapiurl}")
    private String MCAPI;



    //递归检查的排除员工 录入工号;
    @Value("${syncuser.empno}")
    private String OUTRECURSIONEMPNO;

    @Autowired
    private ContractManagementRepository oaSecurityLevelRepository;

    @Autowired
    private IamLeaveUserRepository iamLeaveUserRepository;

    @Getter
    @Setter
    private List<PostPersonalAccountDetailResponse.ErrorMsgDetail> accountErrMsgs = new ArrayList<>();

    //预算查询接口
    public BigDecimal getBudget(String orgBizCode, String subjectBizCode, String strDate, int quarterNo) throws Exception {
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd");
        //OA日期格式化
        Date oaDate = sdf1.parse(strDate);
        try {
            PostBudgetRequest req = new PostBudgetRequest();
            req.setOrgBizCode(orgBizCode);
            req.setSubjectBizCode(subjectBizCode);
            PostBudgetResponse rsp = this.maycurApiService.getMaycurOpenApiClient().execute(req);
            log.info("预算请求返回：{}", JSONObject.toJSONString(rsp));
            List<PostBudgetResponse.Data.BudgetPlans> lists = rsp.getData().getBudgetPlans();
            List<PostBudgetResponse.Data.BudgetPlans.Budgets> budgetses = new ArrayList<>();
            int count = 0;
            for (PostBudgetResponse.Data.BudgetPlans bp : lists) {
                //特殊需求 只要季度预算
                // if ("YEARLY".equals(bp.getCompilationDimension())) {
                //    continue;
                // }
                Date mcEndDay = sdf2.parse(bp.getEndDay());
                Date mcStartDay = sdf2.parse(bp.getStartDay());
                if (bp.getEnabled() && oaDate.compareTo(mcStartDay) >= 1 && oaDate.compareTo(mcEndDay) <= 0) {
                    //可用且时间跨度符合要求
                    budgetses.addAll(bp.getBudgets());
                    count++;
                }

            }
            if (count == 1) {
                //只有一条符合要求
                List<PostBudgetResponse.Data.BudgetPlans.Budgets.BudgetUnits> budunits = budgetses.get(0).getBudgetUnits();
                for (PostBudgetResponse.Data.BudgetPlans.Budgets.BudgetUnits unit : budunits) {
                    //挑选符合要求的记录
                    if (unit.getPeriodNum() == quarterNo) {
                        log.info("获取到符合要求的预算记录:{}", JSONObject.toJSONString(unit));
                        return unit.getUsableAmount();
                    }
                }
            }

            return new BigDecimal(-1.00);
        } catch (Exception exception) {
            exception.printStackTrace();
            //钉钉报错
            return new BigDecimal(-1.00);
        }
    }

    //---------------------员工信息

    /**
     * 根据员工工号查询部门信息
     *
     * @param employeeId
     */
    public String getEmployeeDept(String employeeId) {
        List<PostEmployeeDeptRequest.Employee> employees = new ArrayList<>();
        PostEmployeeDeptRequest.Employee employee = new PostEmployeeDeptRequest.Employee();
        employee.setEmployeeId(employeeId);
        employees.add(employee);
        PostEmployeeDeptRequest req = new PostEmployeeDeptRequest();
        req.setEmployeeList(employees);
        try {
            PostEmployeeDeptResponse rsp = this.maycurApiService.getMaycurOpenApiClient().execute(req);
            if (rsp.getData() == null) {
                return null;
            }
            List<PostEmployeeDeptResponse.Department> rspList = rsp.getData();
            if (rspList.size() > 0 && rspList.size() < 2) {
                //只有一个部门
                PostEmployeeDeptResponse.Department dep = rspList.get(0);
                return dep.getBusinessCode();
            } else if (rspList.size() >= 2) {
                log.info("获取每刻部门接口，用户{}有多个部门，默认取第一个", employeeId);
                PostEmployeeDeptResponse.Department dep = rspList.get(0);
                return dep.getBusinessCode();

            } else {
                log.info("获取每刻部门接口，无法获取用户{} 部门ID", employeeId);
                return null;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }

    }

    public String getEmployeeDeptName(String employeeId) {
        List<PostEmployeeDeptRequest.Employee> employees = new ArrayList<>();
        PostEmployeeDeptRequest.Employee employee = new PostEmployeeDeptRequest.Employee();
        employee.setEmployeeId(employeeId);
        employees.add(employee);
        PostEmployeeDeptRequest req = new PostEmployeeDeptRequest();
        req.setEmployeeList(employees);
        try {
            PostEmployeeDeptResponse rsp = this.maycurApiService.getMaycurOpenApiClient().execute(req);
            if (rsp.getData() == null) {
                return null;
            }
            List<PostEmployeeDeptResponse.Department> rspList = rsp.getData();
            if (rspList.size() > 0 && rspList.size() < 2) {
                //只有一个部门
                PostEmployeeDeptResponse.Department dep = rspList.get(0);
                return dep.getName();
            } else if (rspList.size() >= 2) {
                log.info("获取每刻部门接口，用户{}有多个部门，默认取第一个", employeeId);
                PostEmployeeDeptResponse.Department dep = rspList.get(0);
                return dep.getName();

            } else {
                log.info("获取每刻部门接口，无法获取用户{} 部门ID", employeeId);
                return null;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }

    }

    /**
     * 工号查询员工详情-单用户 返回电话号码
     *
     * @param employeeId
     */
    public String getEmployeeDetails(String employeeId) {
        List<String> list = new ArrayList<>();
        list.add(employeeId);
        PostEmployeeDetailsRequest request = new PostEmployeeDetailsRequest();
        request.setEmployeeIds(list);
        try {
            PostEmployeeDetailsResponse response = this.maycurApiService.getMaycurOpenApiClient().execute(request);
            List<PostEmployeeDetailsResponse.UserDetail> userDetails = response.getData();
            if (userDetails != null && userDetails.size() > 0) {
                PostEmployeeDetailsResponse.UserDetail userDetail = userDetails.get(0);
                String maycurPhone = userDetail.getPhoneNo();
                String maycurName = userDetail.getEmployeeName();
                JSONObject ret = new JSONObject();
                ret.put("maycurPhone", maycurPhone);
                ret.put("maycurName", maycurName);
                return maycurPhone;
            } else {
                return null;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * 根据工号 查询每刻 员工部门
     */
    public String getEmployeeDetailsToDept(String employeeId, String deptName) {
        PostEmployeeDetailsRequest request = new PostEmployeeDetailsRequest();
        request.setEmployeeIds(Arrays.asList(employeeId));
        try {
            PostEmployeeDetailsResponse response = this.maycurApiService.getMaycurOpenApiClient().execute(request);
            List<PostEmployeeDetailsResponse.UserDetail> userDetails = response.getData();
            if (!userDetails.isEmpty()) {
                PostEmployeeDetailsResponse.UserDetail userDetail = userDetails.get(0);
                List<PostEmployeeDetailsResponse.RTRoute> deptList = userDetail.getDepartments();
                String businessCode = "";
                for (PostEmployeeDetailsResponse.RTRoute route : deptList) {
                    businessCode = route.getBusinessCode();
                }
                return businessCode;
            } else {
                return null;
            }
        } catch (Exception ex) {
            return null;
        }
    }


    /**
     * 更新员工银行账号
     * 如果有错误，取消继续更新，同时返回失败原因
     */
    public void setPersonalAccount(List<PostPersonalAccountDetailRequest.Employee> employees) {
        PostPersonalAccountDetailRequest req = new PostPersonalAccountDetailRequest();
        req.setDataList(employees);
        try {
            PostPersonalAccountDetailResponse rsp = this.maycurApiService.getMaycurOpenApiClient().execute(req);
            if (rsp.getData() != null && rsp.getData().getHasErrorMsg().equals("true")) {
                this.accountErrMsgs.addAll(rsp.getData().getErrorMsgDetail());
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 更新员工信息 独立版用接口
     */
    public void pushMaycurEmployeeFunction(List<PostEmployeeBatchRequest.User> users) {
        PostEmployeeBatchRequest req = new PostEmployeeBatchRequest();
        req.setUsers(users);
        try {
            PostEmployeeBatchResponse rsq = this.maycurApiService.getMaycurOpenApiClient().execute(req);
            log.info("更新员工信息返回：{}", JSONObject.toJSONString(rsq));
        } catch (Exception ex) {
            ex.printStackTrace();

        }
    }

    /**
     * 每刻员工离职 独立版用接口
     */
    public void handleEmployeeLeave(){
        List<IamLeaveUser> rets=iamLeaveUserRepository.getLists(2);

        //整理数据
        List<DeleteEmployeeBatchRequest.EmployeeId> reqList = new ArrayList<>();
        for (IamLeaveUser user : rets) {
            DeleteEmployeeBatchRequest.EmployeeId eid = new DeleteEmployeeBatchRequest.EmployeeId(user.getEmployeeno());
            reqList.add(eid);
        }

        if (reqList.isEmpty()) {
            log.info("无新离职人员信息");
            return;
        }
        DeleteEmployeeBatchRequest request = new DeleteEmployeeBatchRequest();
        request.setEmployeeIds(reqList);
        try {
            this.maycurApiService.getMaycurOpenApiClient().execute(request);
        } catch (MaycurException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 推送 ehr员工基础信息 到每刻接口 单一用户
     * userinfo + accountInfo
     *
     * @param jobNumber
     * @param list
     */
    public void employEhrToMayCurByUserId(String jobNumber, List<EhrEmployeeInfo> list) {
        if (list.size() == 0) {
            log.info("传入带更新用户表为空,请检查");
            return;
        }
        List<EhrEmployeeInfo> tmp = null;
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getJobNumber().equals(jobNumber)) {
                tmp = list.subList(i, i + 1);
                break;
            }
        }
        if (tmp != null) {
            //推送分开，员工信息
            pushUserInfoToMaycur(tmp);
            //推送分开, 员工账号
            pushUserAccountToMaycur(tmp);
        }

    }


    //同步每刻用户信息用------------------------------------
    /**
     * 同步ehr账号到 每刻系统中 批量推送（可以用于同步）
     *
     * @param list
     */
    public void employEhrToMayCur(List<EhrEmployeeInfo> list) {
        if (list.size() == 0) {
            log.info("传入数组为空,请检查");
            return;
        }
        //每段长度 默认100 不能超过200
        int count = 100;
        //总数
        int size = list.size();
        //传送次数
        int seg = size / count;
        //是否除尽
        seg = size % count == 0 ? seg : seg + 1;

        List<EhrEmployeeInfo> tmp = null;
        for (int i = 0; i < seg; i++) {
            if (i == seg - 1) {
                //就一段
                tmp = list.subList(count * i, size);
            } else {
                tmp = list.subList(count * i, count * (i + 1));
            }
            //推送分开，员工信息
            pushUserInfoToMaycur(tmp);

        }
        log.info("更新（MAYCUR员工信息）完成");
    }

    //推送到每刻 员工账号
    private void pushUserAccountToMaycur(List<EhrEmployeeInfo> list) {
        //整理推送信息
        List<PostEmployeeBatchRequest.User> reqUserList = new ArrayList<>();
        List<PostPersonalAccountDetailRequest.Employee> reqAccountList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            EhrEmployeeInfo eeinfo = list.get(i);
            if (NormalUtil.null2String(eeinfo.getJobNumber()).equals("")) {
                log.info("--------------------员工对象工号为空（不更新）：ID " + eeinfo.getUserID() + "｜｜ Name " + eeinfo.getName());
                continue;
            }
            //更新员工账号信息  单独接口---------------------
            PostPersonalAccountDetailRequest.Employee userAcc = new PostPersonalAccountDetailRequest.Employee();
            List<PostPersonalAccountDetailRequest.Account> accList = new ArrayList<>();
            PostPersonalAccountDetailRequest.Account account = new PostPersonalAccountDetailRequest.Account();
            //账号人员关系
            userAcc.setEmpId(eeinfo.getJobNumber());
            //账号信息
            account.setAccountName(eeinfo.getName());
            account.setAccountNumber(eeinfo.getAccountNum());
            account.setPaymentType("BANK");

            accList.add(account);
            userAcc.setAccountList(accList);
            reqAccountList.add(userAcc);
        }

        try {
            //调用员工账号新增接口
            setPersonalAccount(reqAccountList);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 推送每刻到用户 基本信息
     *
     * @param list
     */
    public void pushUserInfoToMaycur(List<EhrEmployeeInfo> list) {
        //整理推送信息 (100个一组)
        try {
            List<PostEmployeeBatchRequest.User> reqUserList = new ArrayList<>();
            //用户账号自助维护,不做推送同步
            List<PostPersonalAccountDetailRequest.Employee> reqAccountList = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                EhrEmployeeInfo ehrEmployeeInfo = list.get(i);
                if (NormalUtil.null2String(ehrEmployeeInfo.getJobNumber()).equals("")) {
                    log.warn("员工对象工号为空（不更新）：ID " + ehrEmployeeInfo.getUserID() + "｜｜ Name " + ehrEmployeeInfo.getName());
                    continue;
                }

                if (OUTRECURSIONEMPNO.contains(ehrEmployeeInfo.getJobNumber())) {
                    //跳过更新的特殊人员
                    continue;
                }
                //ZJBS002792
                //更新员工基础信息 单据接口------------------------
                PostEmployeeBatchRequest.User user = new PostEmployeeBatchRequest.User();
                //必填项
                user.setEmployeeId(ehrEmployeeInfo.getJobNumber());
                user.setEmployeeName(ehrEmployeeInfo.getName().replaceAll("\\d+",""));
                user.setEmail(ehrEmployeeInfo.getEmail());

                //更新手机号
                user.setPhoneNo(ehrEmployeeInfo.getMobilePhone());
                //更新职级
                // if (StringUtils.isNotBlank(ehrEmployeeInfo.getZhiji())){
                //    user.setClassPositionBizCode("001");
                // }
                //每刻 驻地 是否需要更新 如果ehr为空,就不更新
                if (StringUtils.isNotBlank(ehrEmployeeInfo.getZhudi())) {
                    List<PostEmployeeBatchRequest.PlaceInfo> placeInfos = new ArrayList<>();
                    PostEmployeeBatchRequest.PlaceInfo placeInfo = new PostEmployeeBatchRequest.PlaceInfo();
                    placeInfo.setPlaceCode(covPlace(ehrEmployeeInfo.getZhudi()));
                    placeInfos.add(placeInfo);
                    user.setResidences(placeInfos);
                }

                //员工上级
                if (StringUtils.isNotBlank(ehrEmployeeInfo.getPoid())) {
                    List<PostEmployeeBatchRequest.RTRoute> rtRoutes = new ArrayList<>();
                    PostEmployeeBatchRequest.RTRoute rtRoute = new PostEmployeeBatchRequest.RTRoute();
                    rtRoute.setSupervisorEmployeeId(ehrEmployeeInfo.getPoName());
                    rtRoute.setBusinessCode(getEmployeeDept(ehrEmployeeInfo.getJobNumber()));
                    rtRoutes.add(rtRoute);
                    user.setDepartments(rtRoutes);
                }

                user.setDefaultLegalEntityBizCode(ehrEmployeeInfo.getDefaultLegalEntityBizCode());
                reqUserList.add(user);
            }
            //调用接口方法推送每刻员工信息
            pushMaycurEmployeeFunction(reqUserList);
        } catch (Exception ex) {
            ex.printStackTrace();
            log.info("EHR与MAYCUR同步异常--->>>>");
        }
    }

    /**
     * 工号查询员工详情-单用户 校验是否相同
     * 检查员工信息(姓名)是否相同
     */
    @Deprecated
    private boolean getEmployeeDetailsRspJson(EhrEmployeeInfo emp) {
        List<String> list = new ArrayList<>();
        list.add(emp.getJobNumber());
        PostEmployeeDetailsRequest request = new PostEmployeeDetailsRequest();
        request.setEmployeeIds(list);
        try {
            PostEmployeeDetailsResponse response = this.maycurApiService.getMaycurOpenApiClient().execute(request);
            List<PostEmployeeDetailsResponse.UserDetail> userDetails = response.getData();
            if (userDetails != null && userDetails.size() > 0) {
                PostEmployeeDetailsResponse.UserDetail userDetail = userDetails.get(0);
                String maycurPhone = userDetail.getPhoneNo();
                String maycurName = userDetail.getEmployeeName();
                if (maycurName.equals(emp.getName())) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }

    /**
     * 自定义档案获取（客户信息）
     */
    private void tradingPartnerGet() throws Exception {
        PostReferenceDataDetailQueryRequest req = new PostReferenceDataDetailQueryRequest();
        req.setReferenceDataBizCode("RD211118ZNNJFK0");

        PostReferenceDataDetailQueryResponse rsp = this.maycurApiService.getMaycurOpenApiClient().execute(req);
        System.out.println("--------" + JSONObject.toJSONString(rsp));

    }

    /**
     * 自定义档案 客户信息获取
     *
     * @throws Exception
     */
    public JSONArray getMaycurTrading(String name) throws Exception {
        try {
            PostReferenceDataDetailQueryRequest request = new PostReferenceDataDetailQueryRequest();
            request.setReferenceDataBizCode("RD211118ZNNJFK0");
            request.setKeyword(name);
            PostReferenceDataDetailQueryResponse rsp = this.maycurApiService.getMaycurOpenApiClient().execute(request);
            log.info("获取自定义档案 模糊查询客户返回报文：{}", JSONObject.toJSONString(rsp));
            JSONArray rspJsons = new JSONArray();
            List<PostReferenceDataDetailQueryResponse.ResultList> lists = rsp.getData().getList();
            for (PostReferenceDataDetailQueryResponse.ResultList r : lists) {
                rspJsons.add(r);
            }
            return rspJsons;
        } catch (MaycurException e) {
            e.printStackTrace();
            return null;
        }

    }

    /**
     * 往来单位同步+推送
     * 同步不做，只做推送，供应商和客户使用同一个方法
     * 用的原有方法，/api/openapi/tradingPartner/data/detail 新方法无法获取不正确的内容
     */
    public String tradingPartnerBatch(MayCurPartner partner) throws Exception {
        StringBuilder sb = new StringBuilder();
        //博圣公司
        PostTradingPartnerDataDetailRequest req = new PostTradingPartnerDataDetailRequest();
        //体外公司
        PostTradingPartnerDataDetailRequest reqSide = new PostTradingPartnerDataDetailRequest();
        PostTradingPartnerDataDetailRequest.TradingPartnerData data = new PostTradingPartnerDataDetailRequest.TradingPartnerData();
        //博圣公司
        List<PostTradingPartnerDataDetailRequest.TradingPartnerData> list = new ArrayList<>();
        //体外公司
        List<PostTradingPartnerDataDetailRequest.TradingPartnerData> listSide = new ArrayList<>();
        List<PostTradingPartnerDataDetailRequest.Account> accounts = new ArrayList<>();
        //主表
        data.setParentName(partner.getParentName());
        data.setName(partner.getName());
        data.setPartnerType(partner.getPartnerType());
        data.setPartnerProperty(partner.getPartnerProperty());
        data.setBusinessCode(partner.getBusinessCode());
        data.setReMark(partner.getReMark());

        //账号
        if (!partner.getAccounts().isEmpty()) {
            for (Map<String, String> m : partner.getAccounts()) {
                PostTradingPartnerDataDetailRequest.Account account = new PostTradingPartnerDataDetailRequest.Account();
                account.setAccountType(m.get("accountType"));
                account.setAccountName(m.get("accountName"));
                account.setAccountNumber(m.get("accountNumber"));
                account.setBankBranchNo(m.get("bankBranchNo"));
                accounts.add(account);
            }
            data.setAccounts(accounts);
        }
        list.add(data);
        req.setPartnerList(list);
        //博圣公司推送
        PostTradingPartnerDataDetailResponse rsp = this.maycurApiService.getMaycurOpenApiClient().execute(req);
        //体外公司：清除分组
        data.setParentName("");
        listSide.add(data);
        reqSide.setPartnerList(listSide);
        //体外公司推送
        PostTradingPartnerDataDetailResponse rspSide = this.maycurApiService.getMaycurOpenApiClientSide().execute(reqSide);
        //博圣相应处理
        for (PostTradingPartnerDataDetailResponse.ErrorData ed : rsp.getData()) {
            if (!ed.getStatus().equals("SUCCESS")) {
                log.info("往来客户({})Push异常，请检查：{}", ed.getBusinessCode(), ed.getMessage());
                sb.append("推送异常:" + ed.getBusinessCode() + " msg:" + ed.getMessage());
                sb.append("\n");
            } else {
                log.info("往来客户推送成功");
                //取消 往来单位和 自定义客户 同时推送
//                pushReferenceDetail(partner, "RD211118ZNNJFK0");
            }
        }
        // 体外公司响应处理
        for (PostTradingPartnerDataDetailResponse.ErrorData ed : rspSide.getData()) {
            if (!ed.getStatus().equals("SUCCESS")) {
                log.info("【体外公司】往来客户({})Push异常：{}", ed.getBusinessCode(), ed.getMessage());
                sb.append("推送异常:" + ed.getBusinessCode() + " msg:" + ed.getMessage());
                sb.append("\n");
            } else {
                log.info("【体外公司】往来客户推送成功");
            }
        }

        if (sb.length() == 0) {
            sb.append("往来客户推送服务完成");
        }
        log.info("往来客户推送服务完成");
        return sb.toString();
    }

    /**
     * 请求新增或更新 往来单位的账号信息
     * @param partner
     */
    public String tradingPartnerBatchAccount(MayCurPartner partner) {
        List<Map<String, String>> _list = partner.getAccounts();
        JSONArray accounts = new JSONArray();
        for (Map<String, String> _map : _list) {
            JSONObject account = new JSONObject();
            account.put("accountType","BANK");
            account.put("accountName",_map.getOrDefault("accountName",""));
            account.put("accountNumber",_map.getOrDefault("accountNumber", ""));
            account.put("bankBranchNo",_map.getOrDefault("bankBranchNo", ""));
            accounts.add(account);
        }
        JSONObject request = new JSONObject();
        request.put("businessCode", partner.getBusinessCode());
        request.put("accounts", accounts);
        request.put("sourceType", "ALL");
        JSONArray requestArray = new JSONArray();
        requestArray.add(request);

        //请求
        try {
            //博圣公司往来单位账号更新路径
            JSONObject tokenInfo = maycurApiService.getToken();
            String requestUrl=String.format("%s%s", "https://ng.maycur.com", "/api/openapi/tradingPartner/batch/account/save");
            String ret = maycurApiService.doPostForMaycur(requestUrl, tokenInfo, JSONObject.toJSONString(requestArray));
            log.info("更新每刻往来客商的账号信息结果------->>>{}", ret);

            //体外公司处理往来单位账号更新
            JSONObject tokenInfoSide = maycurApiService.getTokenSide();
            String retSide = maycurApiService.doPostForMaycur(requestUrl, tokenInfoSide, JSONObject.toJSONString(requestArray));
            log.info("【体外公司】更新每刻往来客商的账号信息结果: {}", retSide);

            return partner.getName() + "账号更新成功:\n博圣公司返回：" + ret + "\n体外公司返回：" + retSide;
        } catch (Exception e) {
            e.printStackTrace();
            return partner.getName() + "账号更新异常!";
        }

    }

    /**
     * 和往来客户类似的，自定义档案推送。（但入参很少，自定义档案名称：RD211118ZNNJFK0）
     * 使用partner对象入参
     */
    public String pushReferenceDetail(MayCurPartner partner, String groupId) {
        PostReferenceDataDetailRequest req = new PostReferenceDataDetailRequest();
        //自定义档案 组ID
        req.setBizCode(groupId);
        List<PostReferenceDataDetailRequest.ReferenceData> lists = new ArrayList<>();
        PostReferenceDataDetailRequest.ReferenceData data = new PostReferenceDataDetailRequest.ReferenceData();
        data.setFullCategoryName(partner.getParentName());
        data.setName(partner.getName());
        data.setBizCode(partner.getBusinessCode());
        data.setEnabled(true);
        lists.add(data);
        req.setReferenceDataDetails(lists);
        try {
            PostReferenceDataDetailResponse rsp = this.maycurApiService.getMaycurOpenApiClient().execute(req);
            JSONObject rspJson = (JSONObject) JSONObject.toJSON(rsp);
            if (rspJson.getBoolean("success")) {
                log.info("推送 自定义档案（客户）成功");
                return "1";
            } else {
                log.info("推送 自定义档案（客户）异常：{}", JSONObject.toJSONString(rspJson));
                return "-1";
            }
        } catch (MaycurException e) {
            e.printStackTrace();
            log.info("推送客户（自定义档案异常）");
            return "-1";
        }

    }


    /**
     * 使用报销单进行导入 接口字段在不停的变化。
     * 报销单 单据导入 主表+明细
     * 返回map
     *
     * @param maint
     * @throws Exception
     */
    public Map<String, Object> addReceiveReimburse(MayCurWPLYInfo maint) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        boolean flag = false;
        //明细
        PostReceiveExpenseRequest exReq = new PostReceiveExpenseRequest();
        List<PostReceiveExpenseRequest.Payment> payments = new ArrayList<>();
        List<String> expenseCodes = new ArrayList<>();
        exReq.setEmployeeId(maint.getShenqingr());
        //费用类型 下拉的序号
        String feiyonglx = maint.getFeiyonglx();
        for (MayCurWPLYItems items : maint.getItems()) {
            PostReceiveExpenseRequest.Payment payment = new PostReceiveExpenseRequest.Payment();
            //处理自定义字段
            Map<String, Object> customObj = new HashMap<>();
            customObj.put("CF79", NormalUtil.null2String(items.getLipinmc()));
            //该字段 自定义档案 Key=U8ID  检查下CF80是否存在
            //customObj.put("CF80", checkCF80(items));
            customObj.put("CF81", items.getShenlingsl());
            customObj.put("CF82", amountFormat(items.getHejije()));
            customObj.put("CF83", amountFormat(items.getChengbendj()));
            customObj.put("CF84", items.getLingyongsl());
            customObj.put("CF85", amountFormat(items.getShichangdj()));
            customObj.put("CF86", items.getLipints());
            customObj.put("CF88", items.getXiangguankhname());
            payment.setCustomObject(customObj);
            //处理原生字段
            //领用日期
            Map<String, Long> consumeTimeMap = new HashMap<>();
            consumeTimeMap.put("currentTime", NormalUtil.dateToLong(items.getLingyongrq()));
            payment.setConsumeTime(consumeTimeMap);
            //市场单价
            payment.setConsumeAmount(amountFormat(items.getShijihjje()));
            // 费用类型 礼品(物品领用)--枚举转换  0206
            payment.setExpenseTypeBizCode(FeiYongLXEnum.idToValue(feiyonglx));
            //add list
            payments.add(payment);
        }
        //新增分组推送明细
        //分段容量
        int count = 10;
        //总数
        int size = payments.size();
        int seg = size / count;
        seg = size % count == 0 ? seg : seg + 1;
        List<PostReceiveExpenseRequest.Payment> _payments = null;
        for (int i = 0; i < seg; i++) {
            if (i == seg - 1) {
                //only 一组
                _payments = payments.subList(count * i, size);
                exReq.setExpenseList(_payments);
                PostReceiveExpenseResponse rspDetail = this.maycurApiService.getMaycurOpenApiClient().execute(exReq);
                Map<String, Object> resultMap = rspDetail.getData();
                if (resultMap.get("errorData") != null) {
                    //新增明细异常
                    dingMessageUtil.pushMessage(null,"single导入明细异常，详情：" + JSONObject.toJSONString(resultMap));
                    returnMap.put("code", 0);
                    returnMap.put("data", null);
                    return null;
                } else {
                    JSONArray jsonArray = (JSONArray) resultMap.get("successData");
                    for (int x = 0; x < jsonArray.size(); x++) {
                        JSONObject json = (JSONObject) jsonArray.get(x);
                        expenseCodes.add(json.getString("expenseCode"));
                    }
                }
            } else {
                //正常
                _payments = payments.subList(count * i, count * (i + 1));
                exReq.setExpenseList(_payments);
                PostReceiveExpenseResponse rspDetail = this.maycurApiService.getMaycurOpenApiClient().execute(exReq);
                Map<String, Object> resultMap = rspDetail.getData();
                if (resultMap.get("errorData") != null) {
                    //新增明细异常
                    dingMessageUtil.pushMessage(null,"muti导入明细异常，详情：" + JSONObject.toJSONString(resultMap));
                    returnMap.put("code", 0);
                    returnMap.put("data", null);
                    return null;
                } else {
                    JSONArray jsonArray = (JSONArray) resultMap.get("successData");
                    for (int x = 0; x < jsonArray.size(); x++) {
                        JSONObject json = (JSONObject) jsonArray.get(x);
                        expenseCodes.add(json.getString("expenseCode"));
                    }
                }
            }
        }
        //分段处理结束
        log.info("成功创建每刻报销单明细共：{}", expenseCodes.size());

        //报销单主表
        PostReceiveReimburseRequest req = new PostReceiveReimburseRequest();
        //报销单返回
        PostReceiveReimburseResponse rsp = new PostReceiveReimburseResponse();

        //报销单主表推送
        //单据编码-常量
        req.setFormSubTypeBizCode("FT2112041IRBMKG0");
        req.setSubmittedUserEmployeeId(maint.getShenqingr());
        //开票公司 编码 含转换
        req.setLegalEntityBizCode(LegalEntityBizEnum.convToCode(maint.getShenqingrgs()));
        //承担人
        req.setCoverUserEmployeeId(maint.getShenqingr());
        //承担部门（需要转换）
        req.setCoverDepartmentBizCode(getEmployeeDept(maint.getShenqingr()));
        //申领原因 必填
        req.setReimburseName(maint.getShenlingyy().substring(0, Math.min(maint.getShenlingyy().length(), 79)));
        //备注
        req.setComments("OA流程推送：" + maint.getLiuchengbh() + "|||" + maint.getTexuyq());
        //预算主体
        Map<Object, Object> m = new HashMap<>();
        m.put("CF102", maint.getYusuanzt());
        req.setCustomObject(m);
        //明细 list
        req.setExpenseCodes(expenseCodes);
        rsp = this.maycurApiService.getMaycurOpenApiClient().execute(req);

        //主表自定义字段
//            Map<Object, Object> map_cf77 = new HashMap<>();
//            map_cf77.put("CF77","中国人群多中心大规模单基因遗传病携带者筛查实践及临床应用模式探究（专项）");
//            req.setCustomObject(map_cf77);
        log.info("每刻--物品领用 请求 json:{}", JSONObject.toJSONString(req));
        log.info("每刻-物品领用请求返回：{}", JSONObject.toJSONString(rsp.getData()));

        JSONObject returnJson = (JSONObject) JSONObject.toJSON(rsp);
        if (returnJson.getBoolean("success")) {
            dingMessageUtil.pushMessage(null,"物品领用推送成功");
            returnMap.put("code", 1);
            returnMap.put("data", returnJson.getString("data"));
            return returnMap;
        } else {
            //钉钉推送
            dingMessageUtil.pushMessage(null,"推送物品领用主表异常，请检查日志：" + returnJson.toJSONString());
            returnMap.put("code", 0);
            returnMap.put("data", "请求新增单据失败，请查看log(" + returnJson.toJSONString() + ")");
            return returnMap;
        }
    }

    /**
     * 使用U8id 检查CF80是否存在
     *
     * @param items
     */
    private String checkCF80(MayCurWPLYItems items) {
        String code = items.getXiangguankh();
        try {
            JSONArray jsonArray = getMaycurTrading(code);
            log.info("checkCF80:{}", JSONArray.toJSONString(jsonArray));
            if (jsonArray.size() > 0) {
                return code;
            } else {
                //每刻不存在 先新增到自定义客户档案中 分类为待分类  同时推送财务
                MayCurPartner mayCurPartner = new MayCurPartner();
                mayCurPartner.setParentName("其他");
                mayCurPartner.setName(items.getXiangguankhname());
                mayCurPartner.setBusinessCode(items.getXiangguankh());
                pushReferenceDetail(mayCurPartner, "RD211118ZNNJFK0");
                dingMessageUtil.pushMessage(null,"导入每刻明细时自定义客户不存在，详情：客户<" + items.getXiangguankhname() + "> U8ID:<" + items.getXiangguankh() + "> 处理结果:自动插入(其他!!改分类目录不要删除)");
                return items.getXiangguankh();
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.info("checkCF80-异常:{}", e.toString());
            return null;
        }
    }

    /**
     * 定时提醒合同已用印为归还
     */
    public void contractManagementRemind() {
        // 获取合同管理列表
        List<ContractManagementEntity> contractManagementList = oaSecurityLevelRepository.getContractManagement();

        // 判断是否为空
        if (contractManagementList == null || contractManagementList.isEmpty()) {
            log.info("没有需要提醒的合同。");
            return;
        }

        // 遍历合同管理列表并发送提醒消息
        for (ContractManagementEntity contract : contractManagementList) {
            try {
                // 发送提醒消息
                dingMessageUtil.pushMessage(null,contract.getRemind());
                log.info("已经通知--->{},内容为--->{}",contract.getShenqingr(),contract.getRemind());
            } catch (Exception e) {
                // 捕获异常，防止影响后续提醒发送
                log.error("发送提醒消息失败，合同ID: {}, 错误信息: {}", contract.getRemind(), e.getMessage());
            }
        }

    }


    //单据获取1 接口

    /**
     * 报销单获取
     *
     * @param code
     */
    public void getReceive(String code) {
        try {
            GetFormReimburseRequest req = new GetFormReimburseRequest();
            req.setFormCode(code);
            GetFormReimburseResponse rsp = this.maycurApiService.getMaycurOpenApiClient().execute(req);
            System.out.println("\n\n获取报销单，请求返回---->" + JSONObject.toJSONString(rsp.getData()));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    //单据获取2 接口
    public void getReceiveSelf(String sCode) {
        try {
            String url = "https://ng.maycur.com/api/openapi/receive/expense";
            JSONObject tokenInfo = maycurApiService.getToken();
            String ret = maycurApiService.doGetForMaycur(url, tokenInfo);
            log.info("自定义请求返回------>{}", ret);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


    /**
     * 转换ehr 的 地址为每刻 添加00
     *
     * @param str
     */
    private String covPlace(String str) {

        try {
            if (str != null) {
                return str + "00";
            } else {
                return "";

            }

        } catch (Exception ex) {
            ex.printStackTrace();
            return "";
        }
    }

    /**
     * 获取  map 工号
     *
     * @param str
     * @param map
     * @return
     */
    private String getMapV(String str, Map<String, String> map) {
        if (map.containsKey(str)) {
            return map.get(str);
        } else {
            return "";
        }
    }

    /**
     * 转换每刻 金额 格式
     *
     * @return
     */
    private Map<String, Object> amountFormat(Object o) {
        Map<String, Object> rm = new HashMap<>();
        rm.put("currency", "CNY");
        if (o == null) {
            rm.put("amount", "0");
        }
        rm.put("amount", String.valueOf(o));
        return rm;
    }
}